#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;
const int N = 100010;
int n;//n表示点的个数
int a[N];//用来存储点

void Adjust_Down(int a[] , int parent , int n)
{//此时n表示的是父亲结点
  int child = parent * 2 + 1;//此时找到当前父亲结点的左孩子结点
  while (child < n)
  {//保证孩子结点的序号不超过堆中结点的个数
    if (child + 1 < n && a[child] < a[child + 1])
    {//此时需要保证其右儿子结点不能超过堆中结点的个数并且其右儿子结点的数值比左儿子结点数值大
      child ++;//此时让孩子结点变为右儿子
    }

    if (a[child] > a[parent])
    {//此时表示孩子结点比双亲结点大，所以要将大的数值交换给双亲结点
      swap(a[child] , a[parent]);
      parent = child;
      child = parent *2 + 1;
    }

    else break;//此时表示当前不需要进行调整
  }
}

void Adjust_Up(int a[] , int child)
{//此时为向上调整操作
  int parent = (child - 1) / 2;//找到其双亲结点的位置
  while (child > 0)
  {
    if (a[parent] < a[child])
    {//此时需要将大的数向上调整
      swap(a[parent] , a[child]);
      child = parent;
      parent = (child - 1) / 2;
    }

    else break;//此时不需要进行调整
  }
}

void HeapSort(int a[] , int n)
{
  int end = n - 1;
  while (end > 0)
  {
    swap(a[0] , a[end]);//将第一个值和最后一个值进行交换
    Adjust_Down(a , 0 , end);//将第一位向下调整
    end --;//将最后一个大的数淘汰掉，逐渐将大的数向后扔
  }
}

int main()
{
  cin >> n;
  for (int i = 0 ; i < n ; i ++)
  {
    cin >> a[i];
  }

  //用向下调整的方法创建一个大根堆
  for (int i = (n - 1 - 1) / 2 ; i >= 0 ; i --)
  {
    Adjust_Down(a , i , n);
  }

  HeapSort(a , n);

  for (int i = 0 ; i < n ; i ++)
  {
    cout << a[i] << ' ';
  }

  cout << endl;
  return 0;

}
